<template>
  <!-- 为了达到从文章详情页回到列表时 能还原它的滚动条的位置；1、在组件内监听scoll 实时记录这个位置
    2、再次回到本组件（从详情页回来），去恢复滚动条的位置
    如果这个组件被缓存了，则它会多两个特殊的钩子函数
    activeted(){} 激活
    deactivated(){}失火
  -->
  <div class="scroll-wrapper" @scroll="hScroll" ref="refScroll">
    {{channel.name}}频道的文章信息列表组件 {{Math.random()}}
    <!--
        van-list自带上拉加载更多的效果
        原理：1)数据项在list中
        2)在显示数据时，如果当前的数据不足一屏，它会调用onload去加载数据
        在onload是要通过ajax取回新数据
        ·····把数据追加到list中（list中的数据会越来越多）
        ·····把loading手动设置为false
        ·····判断是否所有的数据已加载完成 如果是 则把finished设为true
        3）如果手动向上拉 且finished不为true，也会调用onload
    -->
    <van-pull-refresh v-model="isLoadingNew" @refresh="onRefresh">
        <van-list
            v-model="loading"
            :finished="finished"
            loading-text="一大波数据正在赶来"
            finished-text="讨厌，人家被你看完了"
            @load="onLoad"
            >
            <!-- van-pull-refresh组件已经集成了下拉刷新的这个功能，直接使用即可 -->
            <!-- van-cell 中的插槽label ： 作用是整体包裹，显示在标题下方。 -->
            <!-- van-grid ：宫格图布局 -->
            <van-cell v-for="(article, idx) in list" :key="idx" :title="article.title" @click="$router.push({
              path:'/article/',
              query:{
                id:article.art_id.toString()
                }
              })">
                <div slot="label">
                <!-- 图片 当前文章有几张图 就用几个宫格 -->
                <van-grid :column-num="article.cover.images.length">
                    <van-grid-item v-for="(img,idx) in article.cover.images" :key="idx">
                    <van-image lazy-load :src="img" />
                    </van-grid-item>
                </van-grid>

                <!-- 文字说明 -->
                <div class="meta">
                    <span>{{article.aut_name}}</span>
                    <span>{{article.comm_count}}评论</span>
                    <span>{{article.pubdate | relativeTime}}</span>
                    <!-- 修改aticleList视图。如果是登录用户，则额外提供一个关闭按钮。可以根据vuex来判断 -->
                    <span class="close" @click.stop="hClose(article)" v-if="$store.state.tokenInfo.token">
                        <van-icon name="cross"></van-icon>
                    </span>
                </div>
                </div>
            </van-cell>
        </van-list>
    </van-pull-refresh>
  </div>
</template>

<script>
import { getArticles } from '@/api/article.js'
export default {
  name: 'ArticleList',
  props: {
    channel: {
      type: Object,
      required: true
    }
  },
  data () {
    return {
      timer: null, // 防抖时间变量
      timestamp: null, // 时间戳变量 用来控制文章获取的顺序
      list: [], // 数据,每一项就是一篇文章
      loading: false, // 是否正在加载
      finished: false, // 是否所有的数据全部加载完成
      isLoadingNew: false // 是否是 下拉刷新中....
    }
  },
  created () {
    // 由于articleList组件是嵌套在vant的tabs组件中，对于tabs来说，它有懒加载的效果，在不点击标签时，articleList组件是不会创建的。
    // 在创建组件时，开启监听事件总线上的'delArticle'事件。 是否存在用户不感兴趣的文章
    console.log('articleList被创建了', Date.now())
    console.log(this.channel, 'created,启动了监听')
    this.$eventBus.$on('delArticle', (obj) => {
      const { articleId, channelId } = obj
      console.log('我这里是', this.channel, '收到了事件', obj)
      // TODO: 是否需要在本文章列表中去删除对应的数据
      this.delArticle(articleId, channelId)
    })
    // 拉黑作者
    this.$eventBus.$on('delAuthor', (obj) => {
      const { authorId, channelId } = obj
      console.log('我这里是', this.channel, '收到了拉黑作者事件', obj)
      // TODO: 是否需要在本文章列表中去删除对应的数据
      this.delAuthor(authorId, channelId)
    })
  },
  activated () {
    // 重新激活的时候找到上次进行的位置
    console.log('激活 activated...activated...activated...activated...')
    if (this.scrollTop) {
      // 恢复滚动条位置
      console.log('上次位置', this.scrollTop)
      this.$refs.refScroll.scrollTop = this.scrollTop
    }
  },
  methods: {
    hScroll () {
      // 监听用户滚动条
      // 保存一下
      // TODO:防抖处理
      if (this.timer) {
        clearTimeout(this.timer)
      }
      this.timer = setTimeout(() => {
        console.log(this.$refs.refScroll.scrollTop)
        // 对象普通的属性， 不是响应式的数据
        this.scrollTop = this.$refs.refScroll.scrollTop
      }, 200)
    },
    async onLoad () {
      // 当组件滚动到底部时，会触发load事件并将loading设置成true。此时可以发起异步操作并更新数据，数据更新完毕后，将loading设置成false即可。若数据已全部加载完毕，则直接将finished设置成true即可。
      // 1、发请求取回数据
      if (!this.timestamp) {
        this.timestamp = Date.now()
      }
      const result = await getArticles(this.channel.id, Date.now())
      console.log(result)
      //   更新时间戳
      this.timestamp = result.data.data.pre_timestamp
      // 2、把数据追加到list arr是一个数组 每一个都是对象 表示当前的文章
      // 加...是把arr中的元素追加到list元素中
      const arr = result.data.data.results
      this.list.push(...arr)
      // 3、加载状态结束
      this.loading = false
      // 4、判断是否全部加载完成
      if (arr.length === 0) {
        this.finished = true
      }
    },
    async onRefresh () {
      // 1. 重发请求，取最新的数据
      const result = await getArticles(this.channel.id, Date.now())
      // 2. 放在list的最前面（数组的头部）
      const arr = result.data.data.results
      this.list.unshift(...arr)
      // 3. 结束loading: isLoadingNew=false
      this.isLoadingNew = false
      // 4. 提示
      this.$toast(`更新${arr.length}条数据`)
    },
    // 用户点击了关闭按钮
    hClose (article) {
      // 通知父组件index.vue去显示弹层
      console.log('当前文章信息', article)
      // 向父组件传递文章编号. 我们通过 大数处理，把文章编号转成了对象，这里要通过toString()恢复
      const authorId = Number(article.aut_id.toString())
      const articleId = article.art_id.toString()
      this.$emit('showMoreAction', { articleId, authorId })
    },
    delArticle (articleId, channelId) {
      // 检查频道id
      if (this.channel.id !== channelId) {
        console.log(this.channel, '这不是我的频道，我不用进一步去搜索')
        return
      }
      // 去在当前的文章列表中搜索是否有 编号是articleId的文章，
      //  1. findIndex会找出下标，如果找不到，返回-1
      const idx = this.list.findIndex(item => {
        return item.art_id.toString() === articleId
      })
      if (idx !== -1) {
        // 如果找到就删除
        this.list.splice(idx, 1)
      }
    },
    delAuthor (authorId, channelId) {
      // 检查频道id
      if (this.channel.id !== channelId) {
        console.log(this.channel, '这不是我的频道，我不用进一步去搜索')
        return
      }
      // 去在当前的文章列表中搜索是否有 编号是articleId的文章，
      //  1. findIndex会找出下标，如果找不到，返回-1
      const idx = this.list.findIndex(item => {
        return item.aut_id.toString() === authorId
      })
      if (idx !== -1) {
        // 如果找到就删除
        this.list.splice(idx, 1)
      }
    }
  }
}
</script>

<style scoped lang='less'>
    .meta {
        display: flex;
        span{
            margin-right: 10px;
        }
    }
    .close{
        // 让它在最右边
        // 它的父级容器是flex的，给当前元素设置左外边距为auto，会让这个元素在父级容器
        // 的最右边
        margin-left:auto;
    }
</style>
